<?php
/*
 * 公共基础、验证登录 控制器
 * */
namespace app\controller\api;



use app\BaseController;
use think\facade\Db;
use think\facade\Log;


class ApiBase extends BaseController
{

    //ajax返回值
    protected array $result = [
        'code' => 200,
        'msg' => 'success',
        'data' => []
    ];

    protected int $mid = 0;//会员id
    protected array $userInfo = [];


    public function initialize()
    {
        parent::initialize(); // TODO: Change the autogenerated stub

        $this->saveLog($this->request);//保存日志

        if($this->request->isOptions()){
            //跨域处理
            json([])->send();exit;
        }

        //获取用户id
        $token = $this->request->header('authorization');
        if($token){
            //验证token
            $token_data = unserialize(encryptCode($token,'DECODE',BASE_DOMAIN));
            if(is_array($token_data) && isset($token_data['uid']) && isset($token_data['key'])) {
                $this->mid = $token_data['uid'];
                $this->userInfo = Db::name('member')->find($this->mid);
            }
        }

    }

    protected function saveLog($request){
        $requestInfo = [
            'ip' => $request->ip(),
            'method' => $request->method(),
            'host' => $request->host(),
            'uri' => $request->url(),
        ];
        // 获取基本信息
        $runtime = number_format(microtime(true) - $this->app->getBeginTime(), 10, '.', '');
        $reqs    = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞';
        $mem     = number_format((memory_get_usage() - $this->app->getBeginMem()) / 1024, 2);


        $logInfo = [
            "{$requestInfo['ip']} {$requestInfo['method']} {$requestInfo['host']}{$requestInfo['uri']}",
            '运行时间'.number_format((float) $runtime, 6) . 's [ 吞吐率：' . $reqs . 'req/s ] 内存消耗：' . $mem . 'kb 文件加载：' . count(get_included_files()),
            '[ info ] [ ROUTE ] ' . var_export($request->route(), true),
            '[ info ] [ HEADER ] ' . var_export($request->header(), true),
            '[ info ] [ PARAM ] ' . var_export($request->param(), true),
            '---------------------------------------------------------------',
        ];
        $logInfo = implode(PHP_EOL, $logInfo) . PHP_EOL;
        Log::record($logInfo);
    }

    /**
     * 获取树结构
     * @param array $data 源数据
     * @param string $table 数据表名称（不含前缀）
     * @param array $map 附加查询条件
     * @param array $order 查询排序
     * @param string $child_field 子节点键名
     * @param string $field 父节点ID字段名称
     * @param string $pk 主键字段名
     * @throws
     * @return void
     *
     * */
    protected function nextList(array &$data,string $table,array $map = [],array $order = [],string $child_field = 'children',string $field='parent_id',string $pk='id'):void
    {
        if(count($data)){
            foreach ($data as &$d){
                $children = Db::name($table)
                    ->where($field,$d[$pk])
                    ->where($map)
                    ->order($order)
                    ->select()->toArray();
                $this->nextList($children,$table,$map,$order,$child_field,$field,$pk);
                $d[$child_field] = $children;
            }
        }
    }

    /**
     * 解析搜索条件
     * @param array $search
     * @param array $map
     * @return void
     * */
    protected function setMap(array $search,array &$map):void
    {
        if(!empty($search)){
            foreach ($search as $s){
                $modifier = $s['typeof'] ?? '';
                $modifier = $modifier && in_array($modifier,['a','b','d','f','s'])?$modifier : 's';
                $temp = input($s['prop'].'/'.$modifier,'');
                $join = $s['join'] ?? false;
                if($join)continue;
                if($s['required'] || (!is_array($temp) && strlen($temp)) || (is_array($temp) && count($temp))){
                    if($s['expression'] === 'like' || $s['expression'] === 'not like'){
                        $map[] = [$s['field'],$s['expression'],"%$temp%"];
                    }elseif($s['expression'] === 'time'){
                        $map[] = [$s['field'],'between time',$temp];
                    }elseif($s['expression'] === 'find'){
                        $map[] = [$s['field'],'find in set',$temp];
                    }else{
                        $map[] = [$s['field'],$s['expression'],$temp];
                    }
                }
            }
        }
    }

    /**
     * 时间计算
     * @param int $start 开始时间(时间戳)
     * @param int $end 结束时间(时间戳)
     * @return string
     * */
    protected function timeBc(int $start,int $end):string
    {
        $cz = $end - $start;//差值
        if($cz > (3600*24*365)){
            $n = intval($cz/(3600*24*365));
            $n = $n < 3 ? $n : 3;
            $str = $n.'年前';
        }elseif($cz > (3600*24*30)){
            $n = intval($cz/(3600*24*30));
            $str = $n < 6 ? $n.'个月前' : '半年前';
        }elseif($cz > (3600*24)){
            $n = intval($cz/(3600*24));
            $str = $n < 7 ? $n.'天前' : '一周前';
        }elseif($cz > 3600){
            $n = intval($cz/3600);
            $str = $n < 12 ? $n.'小时前' : '半天前';
        }elseif($cz > 60){
            $n = intval($cz/60);
            $str = $n < 30 ? $n.'分钟前' : '半小时前';
        }else{
            $str = $cz < 30 ? $cz.'秒前' : '半分钟前';
        }
        return $str;
    }


    /**
     * 时间倒计时计算
     * @param string|int $start 开始时间
     * @param string|int $end 结束时间
     * @return string
     * */
    protected function timeDown(string $start,string $end):string
    {
        if(!is_numeric($start)){
            $start = strtotime($start);
        }
        if(!is_numeric($end)){
            $end = strtotime($end);
        }
        if($end < $start){
            return '已过期';
        }
        $cz = $end - $start;//差值
        if($cz > (3600*24*365)){
            $str = intval($cz/(3600*24*365)).'年后';
        }elseif($cz > (3600*24*30)){
            $str = intval($cz/(3600*24*30)).'月后';
        }elseif($cz > (3600*24)){
            $str = intval($cz/(3600*24)).'天后';
        }elseif($cz > 3600){
            $str = intval($cz/3600).'小时后';
        }else{
            $str = intval($cz/60).'分钟后';
        }
        return $str;
    }

    /**
     * 时间倒计时计算
     * @param string|int $start 开始时间
     * @param string|int $end 结束时间
     * @return string
     * */
    protected function countDown(string $start,string $end):string
    {
        if(!is_numeric($start)){
            $start = strtotime($start);
        }
        if(!is_numeric($end)){
            $end = strtotime($end);
        }
        if($end < $start){
            return '已结束';
        }
        $cz = $end - $start;//差值
        $year = intval($cz/(3600*24*365));
        $cz = $cz % (3600*24*365);
        $month = intval($cz/(3600*24*30));
        $cz = $cz % (3600*24*30);
        $day = intval($cz/(3600*24));
        $cz = $cz % (3600*24);
        $hour = intval($cz/3600);
        $cz = $cz % 3600;
        $minute = intval($cz/60);

        $str = '';
        if($year){
            $str .= $year.'年';
        }
        $str = strlen($str)?$str.$month.'月':($month?$month.'月':'');
        $str = strlen($str)?$str.$day.'天':($day?$day.'天':'');
        $str .= $hour.'小时';
        $str .= $minute.'分钟';

        return $str;
    }

    /**
     * 计算结束时间
     * @param string $start 开始时间
     * @param int $time_long 时长（分钟）
     * @return string
     * */
    protected function getEndTime(string $start,int $time_long):string
    {
        $start  = strstr($start,':') !== false ? $start : date('Y-m-d H:i',$start);
        return date('H:i',strtotime($start.' +'.$time_long.' minute'));
    }


    public function __call($method,$args)
    {
        return $this->request->isAjax() || $this->request->isPost() ? json(['code'=>404,'msg'=>'page not found'],404):'<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>404</title>
    <style>
    html,body{
    height: 99%;
    }
    .content{
        text-align: center;
        height: 100%;
    }
    .content img{
    max-height: 100%;
    max-width: 40%;
    }
</style>
</head>
<body><div class="content"><img src="/static/image/404.svg" /></div></body>
</html>';

    }


}
